<template>
  <div class="jaguar-view">
    <div class="jaguar-search">
      <el-form :inline="true" :model="searchForm" @submit.prevent>
        <search-input
          label="访问账号"
          v-model="searchForm.createBy"
          :search="getData"
        />

        <el-form-item label="接口名称">
          <Select
            v-model="searchForm.apiOperation"
            filter
            showClear
            placeholder="请选择接口名称"
            :options="apiOperations"
            @change="getData"
          />
        </el-form-item>

        <el-form-item label="访问时间">
          <DatePicker
            v-model="searchForm.accessTime"
            showTime
            showSeconds
            selectionMode="range"
            hideOnRangeSelection
            showButtonBar
            style="width: 23rem"
            @hide="getData"
          />
        </el-form-item>

        <Accordion>
          <AccordionPanel value="0">
            <AccordionHeader>高级查询</AccordionHeader>
            <AccordionContent>
              <search-input
                label="authorization"
                v-model="searchForm.authorization"
                :search="getData"
              />
              <search-input
                label="客户端IP"
                v-model="searchForm.clientHost"
                :search="getData"
              />

              <search-select
                label="请求方式"
                v-model="searchForm.method"
                :options="[
                  { label: 'GET', value: 'GET' },
                  { label: 'POST', value: 'POST' },
                  { label: 'PUT', value: 'PUT' },
                  { label: 'DELETE', value: 'DELETE' },
                ]"
                :search="getData"
              />
              <search-input
                label="响应状态码"
                v-model="searchForm.status"
                :search="getData"
              />

              <search-input
                label="模糊请求地址"
                v-model="searchForm.fuzzyRequestUri"
                :search="getData"
              />
              <search-input
                label="模糊客户端引擎"
                v-model="searchForm.fuzzyUserAgent"
                :search="getData"
              />

              <el-form-item label="请求时长">
                <InputNumber
                  v-model="searchForm.minDuration"
                  :min="0"
                  :max="10000000"
                  @update:modelValue="getData"
                />
                -
                <InputNumber
                  v-model="searchForm.maxDuration"
                  :min="1"
                  :max="10000000"
                  @update:modelValue="getData"
                />
              </el-form-item>

              <el-divider>全文检索</el-divider>

              <search-input
                label="请求参数"
                v-model="searchForm.matchParameters"
                :search="getData"
              />
              <search-input
                label="响应结果"
                v-model="searchForm.matchJsonResult"
                :search="getData"
              />
              <search-input
                label="错误信息"
                v-model="searchForm.matchErrorMsg"
                :search="getData"
              />
            </AccordionContent>
          </AccordionPanel>
        </Accordion>
      </el-form>
    </div>

    <div class="m-t-10 m-b-10 t-a-c">
      <search-button :search="getData" />
      <reset-button :search-form="searchForm" :search="getData" />
    </div>

    <Card>
      <template #content>
        <DataTable :value="tableData" :loading="loading">
          <template #header> 总条目数：{{ page.total }} </template>

          <Column>
            <template #body="scope">
              {{ scope.index + 1 }}
            </template>
          </Column>

          <Column header="创建人/Authorization">
            <template #body="scope">
              <div v-if="scope.data.createBy">
                {{ scope.data.createBy }} ({{ scope.data.createUserId }})
              </div>
              <span v-else>匿名</span>
              <div>
                {{ scope.data.authorization }}
              </div>
            </template>
          </Column>

          <Column field="clientHost" header="客户端">
            <template #body="scope">
              {{ scope.data.clientHost }}
              <div>
                {{ scope.data.userAgent }}
              </div>
            </template>
          </Column>

          <Column field="requestUri" header="请求接口">
            <template #body="scope">
              {{ scope.data.apiOperation }}
              <div>
                {{ scope.data.requestUri }}
              </div>
            </template>
          </Column>

          <Column header="请求方式|状态码|耗时">
            <template #body="scope">
              {{ scope.data.method }} | {{ scope.data.status }} |
              {{ scope.data.duration }}
            </template>
          </Column>

          <Column field="accessTime" header="访问时间" />

          <Column header="操作">
            <template #body="scope">
              <view-button @click="handleView(scope.data)" />
            </template>
          </Column>

          <template #footer>
            <div v-if="loadFinished" class="table-bottom">我也是有底线的</div>
            <div v-else @mouseover="load" class="table-bottom">加载更多</div>
          </template>
        </DataTable>
      </template>
    </Card>

    <View :dialog="dialog" />
  </div>
</template>
<script>
import { fetchList, fetchApiOperation } from '@/api/log/handlerLog'
import View from './View'
import moment from 'moment'

export default {
  name: 'HandlerLog',
  data() {
    return {
      loading: false,
      tableData: [],
      searchForm: {},
      page: {
        total: 0,
      },
      dialog: {
        entity: null,
        operation: null,
        visible: false,
      },
      loadFinished: false,
      apiOperations: [],
    }
  },
  components: {
    View,
  },
  mounted() {
    this.getData()
    this.fetchApiOperation()
  },
  methods: {
    getData() {
      if (this.loading) return

      this.searchForm.accessStartTime = null
      this.searchForm.accessEndTime = null
      if (this.searchForm.accessTime) {
        if (this.searchForm.accessTime.length > 0) {
          this.searchForm.accessStartTime = moment(
            this.searchForm.accessTime[0]
          ).format('YYYY-MM-DD HH:mm:ss')
        }
        if (this.searchForm.accessTime.length > 1) {
          this.searchForm.accessEndTime = moment(
            this.searchForm.accessTime[1]
          ).format('YYYY-MM-DD HH:mm:ss')
        }
      }

      this.loading = true
      fetchList(Object.assign({}, this.searchForm))
        .then((res) => {
          let data = res.data.data
          this.tableData = data.records
          this.page.total = data.total

          this.loadFinished = this.page.total == this.tableData.length
        })
        .finally(() => {
          this.loading = false
        })
    },
    load() {
      if (this.loading) return

      let maxId = -1
      if (this.tableData.length > 0) {
        maxId = this.tableData[this.tableData.length - 1].id
      }

      this.searchForm.accessStartTime = null
      this.searchForm.accessEndTime = null
      if (this.searchForm.accessTime) {
        if (this.searchForm.accessTime.length > 0) {
          this.searchForm.accessStartTime = moment(
            this.searchForm.accessTime[0]
          ).format('YYYY-MM-DD HH:mm:ss')
        }
        if (this.searchForm.accessTime.length > 1) {
          this.searchForm.accessEndTime = moment(
            this.searchForm.accessTime[1]
          ).format('YYYY-MM-DD HH:mm:ss')
        }
      }

      this.loading = true
      fetchList(
        Object.assign(
          {
            maxId,
          },
          this.searchForm
        )
      )
        .then((res) => {
          let data = res.data.data
          if (data.records.length == 0) {
            this.loadFinished = true
            return
          }

          this.tableData = this.tableData.concat(data.records)
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleView(row) {
      this.dialog.entity = row
      this.dialog.operation = 3
      this.dialog.visible = true
    },
    fetchApiOperation() {
      fetchApiOperation().then((res) => {
        this.apiOperations = res.data.data
      })
    },
  },
}
</script>
<style lang="scss" scoped>
.table-bottom {
  height: 60px;
  line-height: 60px;
  text-align: center;
}
</style>
